//
//  PPSocializationManager.m
//  pickpic
//
//  Created by Jinxiao on 9/17/16.
//  Copyright © 2016 MicroDream. All rights reserved.
//

#import "PPSocializationManager.h"

#import "WXApi.h"
#import "WeiboSDK.h"
#import <TencentOpenAPI/TencentOAuth.h>
#import <TencentOpenAPI/QQApiInterface.h>

#define WeiXinAppKey     @"wxd0e64e783c4bdc40"
#define WeiXinAppSecret  @"978faf10089885adb6ecfbf9fc4bea6d"
#define WeiXinBundleID   @"com.tencent.xin"

#define TencentAppKey    @"1105619131"
#define QQBundleID       @"com.tencent.mqq"

#define SinaAppKey       @"2816430094"
#define SinaRedirectURI  @"http://www.microdreams.net/"
#define SinaBundleID     @"com.sina.weibo"

@interface PPSocializationManager () <WXApiDelegate, TencentSessionDelegate, WeiboSDKDelegate>
@property (readwrite, nonatomic, strong) TencentOAuth *tendentOAuth;
@property (readwrite, nonatomic, strong) void (^loginCompletion) (PPSocializationType, PPSocializationUserObject *user, NSError *);
@end

@implementation PPSocializationManager

+ (instancetype)sharedInstance {
    static id instance;
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        instance = self.new;
    });

    return instance;
}

- (instancetype)init {
    self = [super init];

    [WXApi registerApp:WeiXinAppKey];

    [WeiboSDK registerApp:SinaAppKey];

    _tendentOAuth = [[TencentOAuth alloc] initWithAppId:TencentAppKey andDelegate:self];

    return self;
}

- (BOOL)support:(PPSocializationType)type {
    switch(type) {
        case PPSocializationTypeWeixin: {
            return [WXApi isWXAppSupportApi];
        }

        case PPSocializationTypeWeibo: {
            return [WeiboSDK isCanSSOInWeiboApp];
        }

        case PPSocializationTypeQQ: {
            return [QQApiInterface isQQSupportApi];
        }

        default: {
            return YES;
        }
    }
}

- (BOOL)handleOpenURL:(NSURL *)openURL {
    return [WXApi handleOpenURL:openURL delegate:self] || [TencentOAuth HandleOpenURL:openURL] || [WeiboSDK handleOpenURL:openURL delegate:self];
}

- (NSError *)loginError {
    return [self errorWithDscription:@"登录失败" errorCode:-1000];
}

- (NSError *)cancelLoginError {
    return [self errorWithDscription:@"取消登录" errorCode:-1001];
}

- (NSError *)errorWithDscription:(NSString *)description errorCode:(NSInteger)errorCode {
    NSDictionary *userInfo;

    if(description.length > 0) {
        userInfo = [NSDictionary dictionaryWithObjectsAndKeys:description, NSLocalizedDescriptionKey, nil];
    }

    NSError *error = [NSError errorWithDomain:@"com.pickpic.error" code:errorCode userInfo:userInfo];

    return error;
}




#pragma mark TencentLoginDelegate

- (void)tencentDidLogin {
    NSString *accessToken = _tendentOAuth.accessToken;
    NSString *openID = _tendentOAuth.openId;

    NSString *URLString = [NSString stringWithFormat:@"https://graph.qq.com/user/get_user_info?openid=%@&access_token=%@&oauth_consumer_key=%@", openID, accessToken, TencentAppKey];

    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
    [manager GET:URLString parameters:nil progress:nil success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {
        if([responseObject valueForKey:@"ret"]) {
            if([[responseObject valueForKey:@"ret"] integerValue] == 0) {
                PPSocializationUserObject *user = [[PPSocializationUserObject alloc] init];
                user.loginID = openID;
                user.name = [responseObject validStringForKey:@"nickname"];
                user.avatar = [responseObject validStringForKey:@"figureurl_qq_2"];
                user.province = [responseObject validStringForKey:@"province"];
                user.city = [responseObject validStringForKey:@"city"];

                NSString *gender = [responseObject validStringForKey:@"gender"];
                if([gender isEqualToString:@"男"]) {
                    user.gender = PPUserGenderMale;
                } else {
                    user.gender = PPUserGenderFemale;
                }

                !_loginCompletion ? : _loginCompletion(PPSocializationTypeWeixin, user, nil);
                _loginCompletion = nil;

            } else {
                !_loginCompletion ? : _loginCompletion(PPSocializationTypeWeixin, nil, [self loginError]);
                _loginCompletion = nil;
            }
        } else {
            !_loginCompletion ? : _loginCompletion(PPSocializationTypeWeixin, nil, [self loginError]);
            _loginCompletion = nil;
        }
    } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {
        !_loginCompletion ? : _loginCompletion(PPSocializationTypeWeixin, nil, error);
        _loginCompletion = nil;
    }];

}

- (void)tencentDidNotLogin:(BOOL)cancelled {
    if(cancelled) {
        !_loginCompletion ? : _loginCompletion(PPSocializationTypeQQ, nil, [self cancelLoginError]);
    } else {
        !_loginCompletion ? : _loginCompletion(PPSocializationTypeQQ, nil, [self loginError]);
    }

    _loginCompletion = nil;
}

- (void)tencentDidNotNetWork {
    !_loginCompletion ? : _loginCompletion(PPSocializationTypeQQ, nil, [self loginError]);
    _loginCompletion = nil;
}


#pragma mark - WXApiDelegate

- (void)onResp:(BaseResp *)resp {

    if([resp isKindOfClass:[SendMessageToWXResp class]]) {
        if(resp.errCode == WXSuccess) {

        } else if(resp.errCode == WXErrCodeUserCancel) {

        } else {

        }
    } else if([resp isKindOfClass:[SendAuthResp class]]) {

        if(resp.errCode == WXSuccess) {

            SendAuthResp *sendAuthResp = (SendAuthResp *)resp;

            NSString *code = sendAuthResp.code;

            NSString *URLString = [NSString stringWithFormat:@"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code", WeiXinAppKey, WeiXinAppSecret, code];

            AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
            manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/plain"];
            [manager GET:URLString parameters:nil progress:nil success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {

                NSString *accessToken = [responseObject validStringForKey:@"access_token"];
                NSString *openID = [responseObject validStringForKey:@"openid"];

                NSString *URLString = [NSString stringWithFormat:@"https://api.weixin.qq.com/sns/userinfo?openid=%@&access_token=%@", openID, accessToken];

                [manager GET:URLString parameters:nil progress:nil success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {
                    if([responseObject objectForKey:@"errcode"]) {
                        !_loginCompletion ? : _loginCompletion(PPSocializationTypeWeixin, nil, [self loginError]);
                        _loginCompletion = nil;
                    } else {
                        PPSocializationUserObject *user = [[PPSocializationUserObject alloc] init];
                        user.loginID = [responseObject validStringForKey:@"openid"];
                        user.name = [responseObject validStringForKey:@"nickname"];
                        user.avatar = [responseObject validStringForKey:@"headimgurl"];
//                        user.province = [responseObject validStringForKey:@"province"];
//                        user.city = [responseObject validStringForKey:@"city"];

                        if([responseObject validNumberForKey:@"sex"].integerValue == 1) {
                            user.gender = PPUserGenderMale;
                        } else {
                            user.gender = PPUserGenderFemale;
                        }

                        !_loginCompletion ? : _loginCompletion(PPSocializationTypeWeixin, user, nil);
                        _loginCompletion = nil;

                    }
                } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {
                    !_loginCompletion ? : _loginCompletion(PPSocializationTypeWeixin, nil, [self loginError]);
                    _loginCompletion = nil;
                }];
            } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {
                !_loginCompletion ? : _loginCompletion(PPSocializationTypeWeixin, nil, error);
                _loginCompletion = nil;
            }];

        } else if(resp.errCode == WXErrCodeUserCancel) {
            !_loginCompletion ? : _loginCompletion(PPSocializationTypeWeixin, nil, [self cancelLoginError]);
            _loginCompletion = nil;
        } else {
            !_loginCompletion ? : _loginCompletion(PPSocializationTypeWeixin, nil, [self loginError]);
            _loginCompletion = nil;
        }
    }
}

#pragma mark WeiboSDKDelegate

- (void)didReceiveWeiboRequest:(WBBaseRequest *)request {
    //DoNothing
}

- (void)didReceiveWeiboResponse:(WBBaseResponse *)response {
    if([response isKindOfClass:WBSendMessageToWeiboResponse.class]) {

    } else if([response isKindOfClass:WBAuthorizeResponse.class]) {
        WBAuthorizeResponse *authorizeResponse = (WBAuthorizeResponse *)response;

        if(authorizeResponse.statusCode == WeiboSDKResponseStatusCodeSuccess) {

            NSString *accessToken = authorizeResponse.accessToken;
            NSString *openID = authorizeResponse.userID;

            NSString *URLString = [NSString stringWithFormat:@"https://api.weibo.com/2/users/show.json?uid=%@&access_token=%@", openID, accessToken];

            AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
            manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/json"];
            [manager GET:URLString parameters:nil progress:nil success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {
                if(responseObject != nil) {
                    PPSocializationUserObject *user = [[PPSocializationUserObject alloc] init];
                    user.loginID = openID;
                    user.name = [responseObject validStringForKey:@"screen_name"];
                    user.avatar = [responseObject validStringForKey:@"avatar_hd"];

                    NSArray *locations = [[responseObject validStringForKey:@"location"] componentsSeparatedByString:@" "];
                    user.province = [locations safeObjectAtIndex:0];
                    user.city = [locations safeObjectAtIndex:1];

                    NSString *gender = [responseObject validStringForKey:@"gender"];
                    if([gender isEqualToString:@"m"]) {
                        user.gender = PPUserGenderMale;
                    } else {
                        user.gender = PPUserGenderFemale;
                    }

                    !_loginCompletion ? : _loginCompletion(PPSocializationTypeWeixin, user, nil);
                    _loginCompletion = nil;

                } else {
                    !_loginCompletion ? : _loginCompletion(PPSocializationTypeWeixin, nil, [self loginError]);
                    _loginCompletion = nil;
                }
            } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {
                !_loginCompletion ? : _loginCompletion(PPSocializationTypeWeixin, nil, error);
                _loginCompletion = nil;
            }];

        } else if(authorizeResponse.statusCode == WeiboSDKResponseStatusCodeUserCancel) {
            !_loginCompletion ? : _loginCompletion(PPSocializationTypeWeixin, nil, [self cancelLoginError]);
            _loginCompletion = nil;
        } else {
            !_loginCompletion ? : _loginCompletion(PPSocializationTypeWeixin, nil, [self loginError]);
            _loginCompletion = nil;
        }
    }
}

@end

@implementation PPSocializationManager (Login)

- (void)login:(PPSocializationType)type completion:(void (^)(PPSocializationType, PPSocializationUserObject *, NSError *))completion {

    _loginCompletion = completion;

    switch(type) {

        case PPSocializationTypeWeixin: {

            SendAuthReq *req = [[SendAuthReq alloc] init];
            req.scope = @"snsapi_userinfo";
            req.state = @"xxx";
            [WXApi sendReq:req];

            break;
        }

        case PPSocializationTypeWeibo: {

            WBAuthorizeRequest *request = [WBAuthorizeRequest request];
            request.redirectURI = SinaRedirectURI;
            request.scope = @"all";
            [WeiboSDK sendRequest:request];

            break;
        }

        case PPSocializationTypeQQ: {

            NSArray *permissions = @[kOPEN_PERMISSION_GET_SIMPLE_USER_INFO];

            BOOL iphoneQQInstalled = [TencentOAuth iphoneQQInstalled];
            [_tendentOAuth authorize:permissions inSafari:!iphoneQQInstalled];

            break;
        }

    }
}

@end


@implementation PPSocializationManager (Share)

- (void)shareTitle:(NSString *)title subtitle:(NSString *)subtitle url:(NSString *)url image:(UIImage *)image type:(PPSocializationShareType)type {
    [self shareTitle:title subtitle:subtitle url:url image:image thumbnail:nil type:type];
}

- (void)shareTitle:(NSString *)title subtitle:(NSString *)subtitle url:(NSString *)url image:(UIImage *)image thumbnail:(UIImage *)thumbnail type:(PPSocializationShareType)type {

    switch(type) {
        case PPSocializationShareTypeWeixinChat:
        case PPSocializationShareTypeWeixinCircle: {

            if (type == PPSocializationShareTypeWeixinChat) {
                [MobClick event:@"40"];
            }
            else
            {
                [MobClick event:@"41"];
            }
            WXMediaMessage *message = [WXMediaMessage message];

            if(url.length > 0) {
                WXWebpageObject *urlObj = [WXWebpageObject object];
                urlObj.webpageUrl = url;
                message.mediaObject = urlObj;
            }

            if(title.length > 0) {
                message.title = title;
            }

            if(subtitle.length > 0) {
                message.description = subtitle;
            }

            if(image != nil) {
                WXImageObject *imageObj = [[WXImageObject alloc] init];
                imageObj.imageData = [image dataByCompressingToConstrainedSize:10*1024*1024];

                if (url.length == 0)
                {
                    message.mediaObject = imageObj;
                }


                message.thumbData = [(thumbnail ?: image) dataByCompressingToConstrainedSize:32*1024];
            }

            SendMessageToWXReq *request = [[SendMessageToWXReq alloc] init];
            request.bText = NO;
            request.message = message;

            switch(type) {
                case PPSocializationShareTypeWeixinChat: request.scene = WXSceneSession; break;

                case PPSocializationShareTypeWeixinCircle: request.scene = WXSceneTimeline; break;

                default: break;
            }

            [WXApi sendReq:request];

            break;
        }

        case PPSocializationShareTypeWeibo: {

            [MobClick event:@"42"];
            WBSendMessageToWeiboRequest *request = [WBSendMessageToWeiboRequest request];

            WBMessageObject *message = [WBMessageObject message];

            NSMutableArray *components = [NSMutableArray array];
            [components addSafeObject:subtitle];
            [components addSafeObject:title];
            [components addSafeObject:url];
            message.text = [components componentsJoinedByString:@" "];

            if(image != nil) {
                WBImageObject *imageObj = [WBImageObject object];
                imageObj.imageData = [image dataByCompressingToConstrainedSize:10*1024*1024];
                message.imageObject = imageObj;
            }

            request.message = message;

            [WeiboSDK sendRequest:request];
            
            break;
        }

        case PPSocializationShareTypeQQChat: {
            NSURL *URL = url.length > 0 ? [NSURL URLWithString:url] : nil;

            NSData *data = [image dataByCompressingToConstrainedSize:1*1024*1024];
            NSData *thumbnailData = [(thumbnail ?: image) dataByCompressingToConstrainedSize:32*1024];

            QQApiObject *object = nil;
            if(URL != nil) {
                object = [QQApiNewsObject objectWithURL:URL title:title description:subtitle previewImageData:data];
            } else {
                object = [QQApiImageObject objectWithData:data previewImageData:thumbnailData title:title description:subtitle];
            }
            SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:object];
            [QQApiInterface sendReq:req];

            break;
        }

        default:
            break;
    }
}

@end
